
#include <iostream>
#include <cassert>
#include <stdlib.h>
#include <sys/shm.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <assert.h>
#include <pthread.h>
#define image_size_max 3200 * 3200

using namespace std;
using namespace cv;

typedef struct
{
    int rows;
    int cols;
    uchar dataPointer[image_size_max * 3];
    int mask_rows;
    int mask_cols;
    uchar maskPointer[image_size_max];

} image_head;

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

#include "TrtEngine.h"
#include <assert.h>
#include <memory>

#include <opencv2/opencv.hpp>
#include <opencv2/hdf.hpp>

#include <cuda_runtime_api.h>
#include <NvInfer.h>
#include <memory>
#include <NvOnnxParser.h>
#include <vector>
#include <numeric>
#include <chrono>
#include "yolov5.h"
#include "timer.hpp"
#define CHECK(status)                              \
    do                                             \
    {                                              \
        cudaError_t err = (status);                \
        if (err != cudaSuccess)                    \
        {                                          \
            fprintf(stderr, "API error"            \
                            "%s:%d Returned:%d\n", \
                    __FILE__, __LINE__, err);      \
            exit(1);                               \
        }                                          \
    } while (0)

struct mainStru
{
    int len;
    void *ptr;
};

void matp(cv::Mat mat)
{
    printf("mat.step[0]=%ld\n", mat.step[0]);                                                //每一行所占字节数目
    printf("mat.step[1]=%ld\n", mat.step[1]);                                                //每个元素所占字节数
    cout << "L::" << __LINE__ << " size:" << mat.size() << " " << mat.step[0] / (4) << endl; //每个元素所占字节数
}
int main(int argc, char *argv[])
{

    for (size_t i = 0; i < 1000; i++)
    {
    }
    return 0;
}
#define LIMIT_MIN(x) (x > 0 ? x : 0)

int dump(mainStru *cam_num, int row_image, int col_image, void *block_data_image)
{
    static TrtEngine *te = nullptr;
    static Yolov5 *yolov5 = nullptr;
    static image_head *buffer_head = nullptr;
    static int32_t buf[32][6] = {2};
    if (te == nullptr)
    {
        te = new TrtEngine();
        yolov5 = new Yolov5();
        // te->loadOnnxEngine(te->path+".onnx"); //转tensorrt
        te->loadTRTEngine(te->path); //转tensorrt
        buffer_head = new image_head;
    }

    buffer_head->rows = row_image;
    buffer_head->cols = col_image;
    memcpy(buffer_head->dataPointer, block_data_image, row_image * col_image * 3);

    cv::Mat img(row_image, col_image, CV_8UC3, buffer_head->dataPointer);
    // img = cv::imread(path);

    Timer t("all:");
    auto pdata = te->ProcessImage(img);
    vector<Output> output;
    yolov5->postresult_trt(pdata, img, output, 0, 5+4);

    for (int i = 0; i < output.size(); i++)
    {
        buf[i][0] = output[i].confidence * 1000.0f;
        buf[i][1] = LIMIT_MIN(output[i].box.x); // output[i].id;
        buf[i][2] = LIMIT_MIN(output[i].box.y); // output[i].id;
        buf[i][3] = output[i].box.width;        // output[i].id;
        buf[i][4] = output[i].box.height;       // output[i].id;
        buf[i][5] = output[i].id;       // output[i].id;
    }

    cam_num->len = output.size();      // yolov5->mStrOutJson.size();
    cam_num->ptr = (void *)&buf[0][0]; // output.data();// (void*) buffer_head->buf; //yolov5->mStrOutJson.c_str();
    // std::cout << output.size() << " " << sizeof(Output) << " add:" << cam_num->ptr << std::endl;
    // cout<<yolov5->mStrOutJson<<endl;
    return 1;
}

extern "C"
{
    int dump_(mainStru *cam_num, int row_image, int col_image, void *block_data_image)
    {
        // cout << cam_num << endl;
        int result = dump(cam_num, row_image, col_image, block_data_image);
        return result;
    }
    // uchar *read_(int cam_num)
    // {
    //     uchar *result = read(cam_num);
    //     return result;
    // }
}
